More simplifications to blkback:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 6 Apr 2006 10:34:14 +0000 (11:34 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 6 Apr 2006 10:34:14 +0000 (11:34 +0100)
 1. Remove blkif->status field as it's really not needed.
 2. Simplify connection logic.
 3. Get rid of atomic_t io_pending. There's no need for
    atomic r-m-w updates to the work-to-do flag, so replace
    with an integer and add barriers where serialisation is
    required.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c

index 477cab4bc60bcffa288476b4931ad99923f93d89..4faf1170697298cbf5c818dda01f96cf3c5fcf0f 100644 (file)
@@ -225,16 +225,16 @@ int blkif_schedule(void *arg)
        while (!kthread_should_stop()) {
                wait_event_interruptible(
                        blkif->wq,
-                       atomic_read(&blkif->io_pending) ||
-                       kthread_should_stop());
+                       blkif->waiting_reqs || kthread_should_stop());
                wait_event_interruptible(
                        pending_free_wq,
-                       !list_empty(&pending_free) ||
-                       kthread_should_stop());
+                       !list_empty(&pending_free) || kthread_should_stop());
+
+               blkif->waiting_reqs = 0;
+               smp_mb(); /* clear flag *before* checking for work */
 
-               atomic_set(&blkif->io_pending, 0);
                if (do_block_io_op(blkif))
-                       atomic_inc(&blkif->io_pending);
+                       blkif->waiting_reqs = 1;
                unplug_queue(blkif);
 
                if (log_stats && time_after(jiffies, blkif->st_print))
@@ -287,12 +287,15 @@ static int end_block_io_op(struct bio *bio, unsigned int done, int error)
  * NOTIFICATION FROM GUEST OS.
  */
 
-irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+void blkif_notify_work(blkif_t *blkif)
 {
-       blkif_t *blkif = dev_id;
-
-       atomic_inc(&blkif->io_pending);
+       blkif->waiting_reqs = 1;
        wake_up(&blkif->wq);
+}
+
+irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       blkif_notify_work(dev_id);
        return IRQ_HANDLED;
 }
 
@@ -512,10 +515,8 @@ static void make_response(blkif_t *blkif, unsigned long id,
        }
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
-       if (more_to_do) {
-               atomic_inc(&blkif->io_pending);
-               wake_up(&blkif->wq);
-       }
+       if (more_to_do)
+               blkif_notify_work(blkif);
        if (notify)
                notify_remote_via_irq(blkif->irq);
 }
index 502a02c6b893a8c421383bc39a4f412aa49aa153..58939d6ab2f4ff92e3b706e4e6fd093cddab02f3 100644 (file)
@@ -72,7 +72,6 @@ typedef struct blkif_st {
        /* Back pointer to the backend_info. */
        struct backend_info *be; 
        /* Private fields. */
-       enum { DISCONNECTED, CONNECTED } status;
 #ifdef CONFIG_XEN_BLKDEV_TAP_BE
        /* Is this a blktap frontend */
        unsigned int     is_blktap;
@@ -82,7 +81,7 @@ typedef struct blkif_st {
 
        wait_queue_head_t   wq;
        struct task_struct  *xenblkd;
-       atomic_t            io_pending;
+       unsigned int        waiting_reqs;
        request_queue_t     *plug;
 
        /* statistics */
@@ -130,11 +129,10 @@ void blkif_interface_init(void);
 
 void blkif_xenbus_init(void);
 
+void blkif_notify_work(blkif_t *blkif);
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 int blkif_schedule(void *arg);
 
-void update_blkif_status(blkif_t *blkif); 
-
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
 
 /*
index 75b9f74b0b9088ba52d63b5538c0a8611aef3f90..c220efcf4bab04d0234410b6446b9cf44c1ee481 100644 (file)
@@ -45,7 +45,6 @@ blkif_t *alloc_blkif(domid_t domid)
 
        memset(blkif, 0, sizeof(*blkif));
        blkif->domid = domid;
-       blkif->status = DISCONNECTED;
        spin_lock_init(&blkif->blk_ring_lock);
        atomic_set(&blkif->refcnt, 1);
        init_waitqueue_head(&blkif->wq);
@@ -138,9 +137,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
        blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
 
-       /* We're potentially connected now */
-       update_blkif_status(blkif); 
-
        return 0;
 }
 
index 636caefdd8340377f4586863f2446c82360fb4fc..d0ec094d66e0a975bff80b376116c183d7a46881 100644 (file)
@@ -17,7 +17,6 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-
 #include <stdarg.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include "common.h"
 
 #undef DPRINTK
-#define DPRINTK(fmt, args...) \
-    pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-
+#define DPRINTK(fmt, args...)                          \
+       pr_debug("blkback/xenbus (%s:%d) " fmt ".\n",   \
+                __FUNCTION__, __LINE__, ##args)
 
 struct backend_info
 {
        struct xenbus_device *dev;
        blkif_t *blkif;
        struct xenbus_watch backend_watch;
-
        unsigned major;
        unsigned minor;
        char *mode;
 };
 
-
-static void maybe_connect(struct backend_info *);
 static void connect(struct backend_info *);
 static int connect_ring(struct backend_info *);
 static void backend_changed(struct xenbus_watch *, const char **,
                            unsigned int);
 
 
-void update_blkif_status(blkif_t *blkif)
+static void update_blkif_status(blkif_t *blkif)
 { 
-       if(blkif->irq && blkif->vbd.bdev) {
-               blkif->status = CONNECTED; 
-               (void)blkif_be_int(0, blkif, NULL); 
+       if (blkif->irq && blkif->vbd.bdev &&
+           (blkif->be->dev->state != XenbusStateConnected)) {
+               connect(blkif->be);
+               blkif_notify_work(blkif);
        }
-       maybe_connect(blkif->be); 
 }
 
 
@@ -91,7 +87,6 @@ static int blkback_remove(struct xenbus_device *dev)
                be->backend_watch.node = NULL;
        }
        if (be->blkif) {
-               be->blkif->status = DISCONNECTED; 
                if (be->blkif->xenblkd)
                        kthread_stop(be->blkif->xenblkd);
                blkif_put(be->blkif);
@@ -185,8 +180,8 @@ static void backend_changed(struct xenbus_watch *watch,
                return;
        }
 
-       if (be->major && be->minor &&
-           (be->major != major || be->minor != minor)) {
+       if ((be->major || be->minor) &&
+           ((be->major != major) || (be->minor != minor))) {
                printk(KERN_WARNING
                       "blkback: changing physical device (from %x:%x to "
                       "%x:%x) not supported.\n", be->major, be->minor,
@@ -290,14 +285,6 @@ static void frontend_changed(struct xenbus_device *dev,
 /* ** Connection ** */
 
 
-static void maybe_connect(struct backend_info *be)
-{
-       if ((be->major != 0 || be->minor != 0) &&
-           be->blkif->status == CONNECTED)
-               connect(be);
-}
-
-
 /**
  * Write the physical details regarding the block device to the store, and
  * switch to Connected state.